package dbAccess;

import java.io.*;
import java.util.*;
import java.util.Date;
import java.sql.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class Doctor {

	private final static String defaultStr = "unknown";
	private int docId;
	private String EmailAddress;	
	private int SIN;
	private String FirstName;
	private String LastName;
	private String PhoneNum;
	private String HomeAddress;
	private String gender;
	private java.sql.Date dateOfBirth;
	private String docRoom;
	private String docBuilding;
	private String password;
	public String creator;
	
	private String statusMsg;

	public Doctor(String creatorIn)
	{
		docId=-1;
		SIN=-1;
		FirstName = defaultStr;
		LastName = defaultStr;
		EmailAddress = defaultStr;
		PhoneNum = defaultStr;
		HomeAddress = defaultStr;
		gender = defaultStr;
		dateOfBirth= java.sql.Date.valueOf("0000-00-00");
		password = defaultStr;
		docRoom= defaultStr;
		docBuilding= defaultStr;
		statusMsg = "";
		creator = creatorIn;
	}
	
	
	public Boolean registerDoc(String action)
	{
		if(action.equals("update"))
		{
			int docId = this.getDocId();
			String updateQuery = "update tbl_doctor set IsDeleted = '1' where DocId = " + docId ;
			DbAccess access = new DbAccess();
			access.ExecuteUpdate(access.connect(), updateQuery);
			Login.Log(creator,"update tbl_doctor set IsDeleted = '1' where DocId = " + docId);
		}
		this.setStatusMsg("");
		String query =  "select SIN, EmailAddress from tbl_doctor where (SIN = " + SIN + 
						" or EmailAddress = '" + EmailAddress + "') AND IsDeleted='0'";
		
		DbAccess access = new DbAccess();
		
		try 
		{
		ResultSet rs = access.ExecuteSelect(access.connect(), query);
		if (rs.next())
		{
			this.setStatusMsg("Doctor already exists.");
			return false;
		}
		}
		catch (SQLException e)
		{
			this.setStatusMsg("Duplication check error occurred: " + e.getMessage());
			return false;
		}
		
		//insert into tbl_person
		query =  "insert into tbl_doctor ";
		query += "(EmailAddress, SIN, FirstName, LastName, Phone, HomeAddress, gender, " +
				 "DateOfBirth, DocRoom, DocBuilding, Password, IsDeleted)";
		query += "values ('" + EmailAddress + "', '" + SIN + "', '"+ FirstName + "', '" + 
				 LastName + "', '" + PhoneNum + "', '" + HomeAddress + "', '"+ gender + "', '" + 
				 dateOfBirth + "', '"+ docRoom + "', '" + docBuilding + "', '" + password + "', '0')"; 
		
		if (!(access.ExecuteUpdate(access.connect(), query)))
		{
			this.setStatusMsg("Could not update tbl_person with doctor information.");
			return false;
		}
		else
		{
			Login.Log(creator, query);
		}
		
		int oldDocId = this.getDocId();
		//store doc ID field
		if (!(evalDocId()))
		{
			return false;
		}
		
		if(action.equals("update"))
		{
			int docId = this.getDocId();
			String updateApptQuery = "update tbl_appointment set tbl_appointment.DocId = " + docId + " where " ;
			updateApptQuery += "tbl_appointment.DocId = " + oldDocId;
			
			String updateDocAccessQuery = "update tbl_doc_patient_access set tbl_doc_patient_access.DocId = " + docId + " where " ;
			updateDocAccessQuery += "tbl_doc_patient_access.DocId = " + oldDocId;
			
			String updateStaffAccessQuery = "update tbl_staff_patient_access set tbl_staff_patient_access.DocId = " + docId + " where " ;
			updateStaffAccessQuery += "tbl_staff_patient_access.DocId = " + oldDocId;
			
			String updatePatientQuery = "update tbl_patient set tbl_patient.DocId = " + docId + " where " ;
			updatePatientQuery += "tbl_patient.DocId = " + oldDocId;
			
			String updateStaffQuery = "update tbl_staff set tbl_staff.DocId = " + docId + " where " ;
			updatePatientQuery += "tbl_staff.DocId = " + oldDocId;
		
			DbAccess access2 = new DbAccess();
			
			access2.ExecuteUpdate(access2.connect(), updateApptQuery);
			Login.Log(creator, updateApptQuery);
			
			access2.ExecuteUpdate(access2.connect(), updateDocAccessQuery);
			Login.Log(creator, updateDocAccessQuery);
			
			access2.ExecuteUpdate(access2.connect(), updateStaffAccessQuery);
			Login.Log(creator, updateStaffAccessQuery);
			
			access2.ExecuteUpdate(access2.connect(), updatePatientQuery);
			Login.Log(creator, updatePatientQuery);
			
			access2.ExecuteUpdate(access2.connect(), updateStaffQuery);
			Login.Log(creator, updateStaffQuery);
			
			this.setStatusMsg(this.getFirstName() + " " + this.getLastName() + " updated with new ID: " + this.getDocId());
			return true;
			
		}
		
		this.setStatusMsg("New doctor created with ID: " + this.getDocId());
		return true;
	}
	
	private Boolean evalDocId()
	{
		DbAccess access = new DbAccess();
		String query =  "select tbl_doctor.DocId from tbl_doctor where tbl_doctor.EmailAddress = '" + 
						this.EmailAddress + "' and tbl_doctor.IsDeleted = '0'";
		
		try
		{
			ResultSet rs = access.ExecuteSelect(access.connect(), query);
			rs.next();
			this.docId = rs.getInt("tbl_doctor.DocId");
			return true;
		}
		catch (SQLException e)
		{
			return false;
		}
	}
	
	//for tbl_doc_patient_access
	public Boolean transferPatientRights(int DocId, int PatientId)
	{
		DbAccess access = new DbAccess();
		Calendar calendar = Calendar.getInstance();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		if(!access.ExecuteUpdate(access.connect(), "INSERT INTO tbl_doc_patient_access (DocId, PatientId, Valid, TimeStamp) VALUES ('" + DocId + "', '" + PatientId + "', '1', '" + dateFormat.format(calendar.getTime()) + "')"))
		{
			this.setStatusMsg("Insert failed.");
			return false;
		}
		Login.Log(creator, "INSERT INTO tbl_doc_patient_access (DocId, PatientId, Valid, TimeStamp) VALUES ('" + docId + "', '" + PatientId + "', '1', '" + DateFormat.getDateTimeInstance().toString() + "')");
		return true;
	}
	
	//for tbl_doc_patient_access
	public Boolean removePatientRights(int DocId, int PatientId)
	{
		DbAccess access = new DbAccess();
		
		
		if(!access.ExecuteUpdate(access.connect(),"DELETE from tbl_doc_patient_access WHERE DocId=" + DocId + " AND PatientId=" + PatientId)) 
		{
			this.setStatusMsg("Update failed.");
			return false;
		}
		Login.Log(creator, "UPDATE tbl_doc_patient_access SET Valid='0' WHERE DocId='" + DocId + "', AND PatientId='" + PatientId + "')");
		return true;
	}

	//for admins
	public Boolean removeDoctor(int DocId)
	{
		DbAccess access = new DbAccess();
		//update patient and staff tables
		
		String query = "INSERT INTO tbl_patient (EmailAddress, SIN, FirstName, LastName, Gender, DateOfBirth, Phone, HomeAddress, " +
				"DocId, HealthCard, CurrentHealth, Password, IsDeleted)" + 
				"SELECT EmailAddress, SIN, FirstName, LastName, Gender, DateOfBirth, Phone, HomeAddress," +
				"'0', HealthCard, CurrentHealth, Password, IsDeleted FROM tbl_patient WHERE DocId='" + DocId + "'";
		if(!access.ExecuteUpdate(access.connect(), query))
		{
			this.setStatusMsg("failed to update patient records");
			return false;
		}
		else
		{
			Login.Log(creator, query);
		}
		
		//set old values to IsDeleted 
		query = "UPDATE tbl_patient SET IsDeleted='1' WHERE DocId='" + DocId + "'";
		if(!access.ExecuteUpdate(access.connect(), query))
		{
			this.setStatusMsg("failed to update patient records");
			return false;
		}
		else
		{
			Login.Log(creator, query);
		}
		
		query = "INSERT INTO tbl_staff (EmailAddress, DocId, HasAccess, SIN, FirstName, LastName, Phone, HomeAddress," +
		"Gender, DateOfBirth, Password, IsDeleted)" + 
		"SELECT EmailAddress, '0', HasAccess, SIN, FirstName, LastName, Phone, HomeAddress," +
		"Gender, DateOfBirth, Password, IsDeleted FROM tbl_staff WHERE DocId='" + DocId + "'";
		if(!access.ExecuteUpdate(access.connect(), query))
		{
			this.setStatusMsg("failed to update staff records");
			return false;
		}
		else
		{
			Login.Log(creator, query);
		}
		
		//set old values to IsDeleted 
		query = "UPDATE tbl_staff SET IsDeleted='1' WHERE DocId='" + DocId + "'";
		if(!access.ExecuteUpdate(access.connect(), query))
		{
			this.setStatusMsg("failed to update staff records");
			return false;
		}
		else
		{
			Login.Log(creator, query);
		}
		
		//update doctor table
		query = "UPDATE tbl_doctor SET IsDeleted=1 WHERE DocId='" + DocId + "'";
		if(!access.ExecuteUpdate(access.connect(), query))
		{
			this.setStatusMsg("failed to update doctor records");
			return false;
		}
		else
		{
			Login.Log(creator, query);
		}
		
		Date now = new Date();
		Calendar calendar = Calendar.getInstance();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd");
		//remove future appointments
		query = "DELETE FROM tbl_appointment WHERE DocId='" + DocId + "' AND Date > '" + dateFormat.format(calendar.getTime()) + "'"; 
		if(!access.ExecuteUpdate(access.connect(), query))
		{
			this.setStatusMsg("failed to update appointment records");
			return false;
		}
		else
		{
			Login.Log(creator, query);
		}
		
		query = "DELETE FROM tbl_doc_patient_access WHERE DocId='" + DocId + "'";
		if(!access.ExecuteUpdate(access.connect(), query))
		{
			this.setStatusMsg("failed to update doctor/patient access records");
			return false;
		}
		else
		{
			Login.Log(creator, query);
		}
		
		query = "DELETE FROM tbl_staff_patient_access WHERE DocId='" + DocId + "'";
		if(!access.ExecuteUpdate(access.connect(), query))
		{
			this.setStatusMsg("failed to update doctor/patient access records");
			return false;
		}
		else
		{
			Login.Log(creator, query);
		}
		
		this.setStatusMsg("Doctor has been deleted");
		return true;
	}
	
	public int getDocId() {
		return docId;
	}

	public void setDocId(int docId) {
		this.docId = docId;
	}

	public int getSIN() {
		return SIN;
	}

	public void setSIN(int sin) {
		SIN = sin;
	}

	public String getFirstName() {
		return FirstName;
	}

	public void setFirstName(String firstName) {
		FirstName = firstName;
	}

	public String getLastName() {
		return LastName;
	}

	public void setLastName(String lastName) {
		LastName = lastName;
	}

	public String getPhoneNum() {
		return PhoneNum;
	}

	public void setPhoneNum(String phoneNum) {
		PhoneNum = phoneNum;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getStatusMsg() {
		return statusMsg;
	}

	public void setStatusMsg(String statusMsg) {
		this.statusMsg = statusMsg;
	}
	public String getDocEmailAddress() {
		return EmailAddress;
	}

	public void setDocEmailAddress(String docEmailAddress) {
		EmailAddress = docEmailAddress;
	}
	public String getHomeAddress() {
		return HomeAddress;
	}


	public void setHomeAddress(String homeAddress) {
		HomeAddress = homeAddress;
	}


	public String getGender() {
		return gender;
	}


	public void setGender(String gender) {
		this.gender = gender;
	}

	public String getDocRoom() {
		return docRoom;
	}


	public void setDocRoom(String docRoom) {
		this.docRoom = docRoom;
	}


	public String getDocBuilding() {
		return docBuilding;
	}


	public void setDocBuilding(String docBuilding) {
		this.docBuilding = docBuilding;
	}

	public java.sql.Date getDateOfBirth() {
		return dateOfBirth;
	}


	public void setDateOfBirth(java.sql.Date dateOfBirth) {
		this.dateOfBirth = dateOfBirth;
	}	
}